查看原文
其他

Stata:读懂直方图

Stata连享会 Stata连享会 2020-02-10

作者:万莉 (北京航空航天大学)    
Stata 连享会:知乎 | 简书 | 码云 | CSDN

2019金秋十月-空间计量专题班,杨海生主讲,成都

特别说明

文中包含的链接在微信中无法生效。请点击本文底部左下角的【阅读原文】,转入本文【简书版】

引言

本推文将详细介绍绘制直方图的各种命令,结构安排如下:第一部分先简单介绍直方图的含义;第二部分着重介绍 Stata 里最基本的命令 histogram;第三部分介绍一些好用的外部命令;最后讨论如何进一步美化图形。

1. 直方图简介

直方图 (histogram) 是用一系列宽度相等、高度不等的矩形表示数据分布的图。矩形的宽度表示数据范围的间隔,矩形的高度表示在给定间隔内数据出现的频数或频率。

直方图与条形图(柱状图)的区别:条形图用矩形宽度表示类别,且宽度都相等,而直方图用宽度表示组距,宽度可以不相等;条形图是分开排列的,而由于分组数据具有连续性,直方图是连续排列的(注:Stata 中也可以对离散变量进行绘直方图)。

Source:  柏满迎等.应用统计学:经济与管理中的数据分析[M].北京:清华大学出版社,2011:36.

2. 基本命令- histogram

本节将详细介绍 Stata 里绘制直方图的最基本命令 histogram。本节结构为:介绍语法结构--绘制连续变量的基本直方图--绘制离散变量的基本直方图--展示两个完整的例子。

2.1 语法结构

执行 help histogram 可查看帮助文件。

其语法结构为:

  1. histogram varname [if] [in] [weight] [, [continuous_opts | discrete_opts] options]

varname 是用于绘制图形的变量,if 是条件语句,in 是范围语句,weight 是权重语句。
continuous_opts 是连续变量可用选项;discrete_opts 是离散变量可用选项;
options 是连续、离散变量公用选项。

histogram 的主要选项如下:

选项类别具体命令解释
连续变量bin(#)设置矩形的数目为#
连续变量width(#)设置矩形的宽度为#
连续变量start(#)设置第一个矩形的起始数值#
默认值为观测值的最小值
离散变量discrete离散变量的直方图必须附加 discrete 选项
离散变量width(#)设置矩形的宽度为#
离散变量start(#)设置第一个矩形的起始数值#
默认值为观测值的最小值
公用选项density按密度绘制直方图
为默认选项
公用选项fraction按比例绘制直方图
公用选项frequency按频数绘制直方图
公用选项percent按百分比绘制直方图
公用选项bar_options设定矩形细节的选项
公用选项binrescale结合 by() 命令时,
自动调节矩形的宽度
公用选项addlabels为矩形添加高度标签
公用选项addlabopts设定高度标签显示细节的选项
公用选项normal附加正态分布曲线
公用选项normopts(line_options)设定正态分布曲线细节
公用选项kdensity附加核密度函数曲线
公用选项kdenopts(kdensity_options)设定核密度函数曲线细节


2.2 连续变量的直方图

本小节将介绍如何绘制连续变量的直方图。

  1. sysuse nlsw88.dta, clear // 调用内置数据


  2. histogram wage, ///

  3. note("注释:矩形的高度对应样本数占总样本的比例,总【面积】为 1")


  4. histogram wage, fraction ///

  5. note("注释:将矩形的【高度】总和限制为 1")


  6. histogram wage, percent ///

  7. note("注释:将矩形的【高度】总和限制为 100")


  8. histogram wage, frequency ///

  9. note("注释:纵坐标为对应的样本数(频数),而非比例")


  10. histogram wage, normal ///

  11. note("注释:附加正态分布曲线")


  12. histogram wage, kdensity ///

  13. note("注释:附加核密度函数曲线")


  14. histogram wage, addlabels ///

  15. addlabopts(mlabposition(12) mlabgap(3) ///

  16. mlabangle(45) mlabsize(vsmall) mlabcolor(navy)) ///

  17. note("注释:每个矩形上方附加一个表示其高度的数字" ///

  18. "addlabopts(...)里的命令分别控制标签位置," ///

  19. "与矩形间距,旋转角度,标签大小,颜色。")

  20. help marker_label_options


  21. histogram wage, by(race) binrescale

  22. graph save "$FIG\fig1-8-1.gph", replace

  23. histogram wage, by(race) ///

  24. note("注释:利用 by(),按 race 变量进行分组")


  25. histogram wage, bin(20) ///

  26. fcolor(none) lcolor(black) ///

  27. lwidth(medium) lpattern(solid) ///

  28. note("注释:bin(#)指定分为几个组别" ///

  29. "fcolor(...)设定设定柱子的填充颜色。" ///

  30. "lcolor(...)设定矩形的轮廓颜色。" ///

  31. "lwidth(...)设定矩形的外边缘线的宽度。" ///

  32. "lpattern(...)设定矩形的外边缘线的类型。")

  33. *可通过命令 graph query linewidthstyle 列示线宽代号。

  34. *可通过命令 palette linepalette 图示线型代号。

  35. *可通过外部命令 palette_all 查看颜色代号。

  36. *运行 ssc install full_palette 即可下载该外部命令。

命令运行结果如下图:

fig1.png

2.3 离散变量的直方图

本小节将介绍如何绘制离散变量的直方图。

  1. sysuse nlsw88.dta, clear // 调用内置数据


  2. histogram grade

  3. graph save d1, replace

  4. histogram grade, discrete

  5. *离散变量的直方图必须附加 discrete 选项

  6. graph save d2, replace

  7. graph combine d1.gph d2.gph // 对比差异

命令运行结果如下图:

fig2.png

2.4 两个完整的例子

首先,我们先看第一个例子——利用 by(...) 进行分组绘制直方图。

  1. sysuse auto, clear

  2. histogram mpg, percent discrete ///

  3. by(foreign, col(1) note(分组指标:汽车产地) ///

  4. title("图3:不同产地汽车里数") ///

  5. subtitle("直方图")) ///

  6. scheme(s1mono) gap(50) ///

  7. ytitle(百分比(%)) xtitle(汽车里数) ///

  8. xlabel(12(2)42)

  9. graph save "fig3-1.gph", replace

  10. graph export "fig3-1.png", replace

  11. /*解释

  12. by(...) 里的命令分别为:按 foreign 变量进行分组,

  13. 图形按单列显示,设置注释,设置标题,设置副标题;

  14. scheme(...) 设定图形模板(可理解为主题);

  15. gap(#) 调节矩形之间间隙的大小;

  16. ytitle(...) 设置 y 轴标题;

  17. xtitle(...) 设置 x 轴标题;

  18. xlabel(12(2)42)设定横坐标刻度标签,

  19. x轴的刻度从 12 开始,到 42 结束,每隔 2 添加一个刻度。

  20. */

第二个例子利用多种绘图选项,绘制了较为复杂的直方图。

  1. sysuse sp500, clear

  2. summarize volume // 基本统计量

  3. #delimit ;

  4. histogram volume, freq normal

  5. graphregion(color(white))

  6. addlabels addlabopts(mlabcolor(g))

  7. xaxis(1 2)

  8. ylabel(0(10)65, grid)

  9. xlabel( 12321 "mean"

  10. 9735 "-1 s.d."

  11. 14907 "+1 s.d."

  12. 7149 "-2 s.d."

  13. 17493 "+2 s.d."

  14. 20078 "+3 s.d."

  15. 22664 "+4 s.d."

  16. ,axis(2) grid)

  17. fcolor(ebg) lcolor(gs8)

  18. lwidth(medium) normopts(lcolor(black))

  19. subtitle("图4:S&P 500 交易量 (2001年1月-12月)")

  20. ytitle(频数)

  21. xtitle("交易量(千笔)") xscale(titlegap(2))

  22. xtitle("", axis(2))

  23. note("数据来源:雅虎!财经数据");

  24. #delimit cr

  25. graph save "fig3-2.gph", replace

  26. graph export "fig3-2.png", replace


  27. help axis_choice_options

  28. help axis_label_options

  29. /*解释

  30. graphregion(color(...)) 设置背景颜色;

  31. xaxis(1 2) 设置双坐标 x 轴;

  32. xlabel(..., axis(2) grid gmax)设置 x 轴标签及刻度,

  33. 其中 axis(2) 表示第二个 x 轴,grid 添加网格线;

  34. normopts(lcolor(black)) 设置正态分布曲线颜色

  35. xscale(titlegap(2)) 设置 x 轴与 x 轴标题间距;

  36. */

上述两个例子的运行结果,如下图:

fig3.png

3. 有用的外部命令

本小节将介绍 8 个有用的外部命令。

3.1 命令1:histbox

命令 histbox 能同时绘制 直方图箱型图

  1. ssc install histbox, replace //下载外部命令

  2. help histbox //generate histogram with boxplot


  3. sysuse auto, clear //调用内置数据

  4. #d ;

  5. histbox mpg, mean freq normal bin(10)

  6. title("汽车里数分布")

  7. xlabel(12(2)42);

  8. #d cr


  9. /*注意:

  10. 该命令默认按比例(fraction)绘制直方图,

  11. 若加上 freq 则是按频数绘制直方图;

  12. 不能用 by 选项进行分组绘图。

  13. */

fig4.png

3.2 命令2:historaj

命令 historaj 在基本直方图上添加了描述性统计。

  1. ssc install historaj, replace //下载外部命令

  2. help historaj //histogram with descriptive statistics


  3. sysuse auto, clear

  4. historaj mpg

  5. /*注意:

  6. 该命令不能用 by 选项进行分组绘图;

  7. 执行命令后需要手动在界面进行设置。

  8. */

fig5.png

3.3 命令3:histoflogx

命令 histoflogx  在绘制直方图时,把横轴改为对数坐标。

  1. net install histoflogx, replace //下载外部命令

  2. * 不能下载,可以用 findit histoflogx

  3. help histoflogx //Histogram with log scale on the x-axis


  4. sysuse auto, clear

  5. histoflogx mpg, bin(9) ///

  6. percent start(`=log(10)') ///

  7. lab(10/20 30 40)

fig6.png

3.4 命令4:eqprhistogram

命令 eqprhistogram 使得每个矩形的面积相等。比如,令直方图有 10 个矩形,则可以看出数据十分位数 (Quartile) 的分布情况。

  1. ssc install eqprhistogram, replace //下载外部命令

  2. help eqprhistogram //equal probability histogram


  3. sysuse auto, clear

  4. eqprhistogram price, ///

  5. bin(10) plot(kdensity price)


fig7.png

3.5 命令5:spechist

命令 spechist 可选用不同方法确定矩形的个数/宽度。

  1. ssc install spechist, replace //下载外部命令

  2. help spechist //可选用不同方法确定矩形的个数/宽度


  3. sysuse citytemp, clear

  4. spechist tempjuly, me(all) ///

  5. kden copt(imargin(small))

  6. * 画出所有方法对应的图形

fig8.png

3.6 命令6:marhis

命令 marhis 可用于分析边际效应。注意该命令仅适用于分析以下三种变量:
(1) 任意连续变量;
(2) 两个连续变量的交乘项;
(3) 连续变量和类别变量的交乘项;
注意:交乘项必须使用因子变量的语法格式。

  1. ssc install marhis, replace //下载外部命令

  2. help marhis

  3. * to produce predictive margins and

  4. * marginal effects plots with histogram

  5. * after regress, logit, xtmixed and mixed


  6. sysuse "nlsw88.dta", clear

  7. reg wage i.industry c.hours##i.union

  8. marhis hours, cate(union) // 连续变量和类别变量的交乘项

fig9.png

如何分析边际效应,可参考此推文 Stata:边际效应分析 。

3.7 命令7:bihist

命令 bihist 可以用来绘制双变量双向直方图。

  1. ssc install bihist, replace //下载外部命令

  2. help bihist


  3. sysuse nlsw88, clear

  4. bihist wage, by(married) ///

  5. tw(color(navy)) ///

  6. tw1(color(maroon))

  7. /*

  8. by(married):以婚姻状态 (married) 分组,

  9. 绘制工资 (wage) 的双向直方图。

  10. tw(color(...)) tw1(color(...)):

  11. 分别设置上下矩形的颜色。

  12. */

fig10.png

3.8 命令8:byhist

命令 byhist 可以用来绘制双变量单向直方图。

  1. ssc install byhist //下载外部命令

  2. help byhist


  3. sysuse nlsw88, clear

  4. byhist wage, by(married) ///

  5. tw1(color(navy)) ///

  6. tw2(color(maroon))

  7. /*

  8. by(married):以婚姻状态 (married) 分组,

  9. 绘制工资 (wage) 的单向直方图。

  10. tw1(color(...)) tw2(color(...)):

  11. 分别设置左右矩形的颜色。

  12. */


fig11.png

4. 进一步美化图形

4.1 如何呈现透明的直方图

在多个图形重叠出现时,设定图形的透明度非常实用。举个例子,假设你在绘制两个变量的直方图时,发现两个直方图有重叠部分,该怎么办呢?

如果我们不设定透明度,直接绘制两个直方图,则图形显示如下:

  1. sysuse "nlsw88.dta", clear

  2. #d ;

  3. twoway (hist wage if union==0,

  4. frac color(eltgreen))

  5. (hist wage if union==1,

  6. frac color(eltblue)),

  7. legend(label(1 "union")

  8. label(2 "Non-union"))

  9. title("错误示范");

  10. #d cr

fig12.png

你会发现上例呈现的图形很丑,蓝色直方图几乎覆盖了下方浅绿色直方图。为了得到更好的图片呈现效果,我们可以设定颜色的透明度。这可以通过两个方法来实现。

第一种方法是,通过选项 fcolor(none) 设定颜色的透明度。

  1. #d ;

  2. twoway (hist wage if union==0,

  3. frac lcolor(gs12) fcolor(gs12))

  4. (hist wage if union==1,

  5. frac fcolor(none) lcolor(black)),

  6. legend(label(1 "union")

  7. label(2 "Non-union"))

  8. title("第一种方法");

  9. #d cr

  10. /*

  11. fcolor(...) 设定矩形的填充颜色。

  12. fcolor(none) 表示无填充颜色。

  13. lcolor(...) 设定矩形的轮廓颜色。

  14. */

fig13.png

第二种方法是,通过选项 color(...%#) 设定颜色的透明度。注意该选项仅适用于 Stata 15 及以上版本。

  1. sysuse "nlsw88.dta", clear

  2. #d ;

  3. twoway (hist wage if union==1,

  4. frac fcolor(black*0.3)

  5. lcolor(red*0.3%100) )

  6. (hist wage if union==0,

  7. frac color(green%40)

  8. lcolor(black)),

  9. legend(label(1 "union")

  10. label(2 "Non-union"))

  11. title("第二种方法");

  12. #d cr

  13. /*

  14. color(color%#)

  15. #的数值越小,透明度越高。

  16. fcolor(...) 设定矩形的填充颜色。

  17. lcolor(...) 设定矩形的轮廓颜色。

  18. */

fig14.png

4.2 如何在同一幅图绘制多个垂直直方图

本小节的灵感源自一个知乎问题:想知道这种类型的图是用什么计量软件做出来的?。本小节的代码虽然不能完全解决这个问题,但希望能提供一些思路,供大家参考和指正。

由于没有该问题的原始数据,故使用 Stata 软件自带的数据文件 nlsw88.dta 进行模拟。该数据包含了 1988 年采集的 2246 个美国妇女的资料。本小节将针对 种族 race、职业 industry 两个变量进行绘图。

  1. ssc install mdesc //下载外部命令

  2. sysuse "nlsw88.dta", clear


  3. keep industry race

  4. labelbook //查看文字-变量对应表

  5. /*

  6. 人种:

  7. 1 white

  8. 2 black

  9. 3 other

  10. 行业:

  11. 1 Ag/Forestry/Fisheries

  12. 2 Mining

  13. 3 Construction

  14. 4 Manufacturing

  15. 5 Transport/Comm/Utility

  16. 6 Wholesale/Retail Trade

  17. 7 Finance/Ins/Real Estate

  18. 8 Business/Repair Svc

  19. 9 Personal Services

  20. 10 Entertainment/Rec Svc

  21. 11 Professional Services

  22. 12 Public Administration

  23. */


  24. mdesc //检查变量是否有缺失值

  25. drop if industry == .


  26. bysort race industry: gen n_race_ind = _N

  27. bysort race: gen n_race = _N

  28. duplicates drop race industry, force

  29. gen ratio = n_race_ind/n_race

  30. // 分人种后,计算每个行业的占比


  31. sort race industry

  32. // 发现人种为黑人和其他时,有的行业缺失

  33. // 补上缺失行业,便于画图时共用 y 轴

  34. drop n_*

  35. save temp.dta, replace

  36. replace race = 2 in 1

  37. replace industry = 2 in 1


  38. replace race = 3 in 2

  39. replace industry = 1 in 2


  40. replace race = 3 in 3

  41. replace industry = 2 in 3


  42. replace race = 3 in 4

  43. replace industry = 6 in 4


  44. replace race = 3 in 5

  45. replace industry = 10 in 5


  46. keep in 1/5

  47. replace ratio = 0


  48. append using "temp.dta"

  49. sort race industry

  50. erase temp.dta


  51. *-第一个直方图的辅助图

  52. graph hbar ratio if race == 1, ///

  53. over(industry, ///

  54. label(grid glpattern(dash))) ///

  55. ylabel(,nolabels grid glpattern(dash)) ///

  56. ytitle("race: white", placement(left)) ///

  57. saving(fig_11.gph, replace)


  58. *-第一个直方图

  59. graph hbar ratio if race == 1, ///

  60. over(industry, ///

  61. label(nolabels grid glpattern(dash))) ///

  62. ylabel(,nolabels grid glpattern(dash)) ///

  63. ytitle("race: white", placement(left)) ///

  64. saving(fig_12.gph, replace)


  65. *-第二个直方图

  66. graph hbar ratio if race == 2, ///

  67. over(industry, ///

  68. label(nolabels grid glpattern(dash))) ///

  69. ylabel(, nolabels grid glpattern(dash)) ///

  70. ytitle("race: black", placement(left)) ///

  71. saving(fig_2.gph, replace)


  72. *-第三个直方图

  73. graph hbar ratio if race == 3, ///

  74. over(industry, ///

  75. label(nolabels grid glpattern(dash))) ///

  76. ylabel(,nolabels grid glpattern(dash)) ///

  77. ytitle("race: others", placement(left)) ///

  78. saving(fig_3.gph, replace)


  79. *-图形合并

  80. graph combine fig_11.gph fig_12.gph ///

  81. fig_2.gph fig_3.gph, ///

  82. col(4) iscale(*0.8) imargin(zero)

此时图形还并不完美,需要借助 graph editor 手动编辑,如下图所示:

fig15.png

锵锵锵, 最后成果图如下:

fig16.png

其它相关命令

  • help tabplot // SJ 16(2): 491--510
    外部命令安装:ssc install tabplot, replace

  • help hist2 // Histograms with more options
    外部命令安装:net install hist2, replace

  • help marginsplot // 分析边际效应

  • help twoway__histogram_gen // 具体介绍参见 SJ 5(2):280--281

相关链接


关于我们

  • Stata 连享会(公众号:StataChina)】由中山大学连玉君老师团队创办,旨在定期与大家分享 Stata 应用的各种经验和技巧。

  • 公众号推文同步发布于 CSDN-Stata连享会 、简书-Stata连享会 和 知乎-连玉君Stata专栏。可以在上述网站中搜索关键词StataStata连享会后关注我们。

  • 点击推文底部【阅读原文】可以查看推文中的链接并下载相关资料。

  • Stata连享会 精彩推文1  || 精彩推文2

联系我们

  • 欢迎赐稿: 欢迎将您的文章或笔记投稿至Stata连享会(公众号: StataChina),我们会保留您的署名;录用稿件达五篇以上,即可免费获得 Stata 现场培训 (初级或高级选其一) 资格。

  • 意见和资料: 欢迎您的宝贵意见,您也可以来信索取推文中提及的程序和数据。

  • 招募英才: 欢迎加入我们的团队,一起学习 Stata。合作编辑或撰写稿件五篇以上,即可免费获得 Stata 现场培训 (初级或高级选其一) 资格。

  • 联系邮件: StataChina@163.com

往期精彩推文

点击查看完整推文列表


欢迎加入Stata连享会(公众号: StataChina)
2019暑期“实证研究方法与经典论文”专题班

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存